#include "CNativeHandler.h"
#include "CNativeHandlerPrivate.h"

#include <QApplication>
#include <QDesktopWidget>
#include <QEvent>
#include <QLayout>
#include <QPaintEvent>
#include <QPainter>

CNativeHandler::CNativeHandler(QWidget *parent) : ModelHandler(parent), w(parent) {
    m_borderColor = Qt::black;
    m_resizable = true;
}

CNativeHandler::~CNativeHandler() {
}

QWidget *CNativeHandler::widget() const {
    return w;
}

QMargins CNativeHandler::resizeMargins() const {
    return m_resizeMargins;
}

void CNativeHandler::setResizeMargins(const QMargins &margins) {
    m_resizeMargins = margins;
}

bool CNativeHandler::resizable() const {
    return m_resizable;
}

void CNativeHandler::setResizable(bool resizable) {
    m_resizable = resizable;
    updateResizable();
}

QColor CNativeHandler::borderColor() const {
    return m_borderColor;
}

void CNativeHandler::setBorderColor(const QColor &borderColor) {
    m_borderColor = borderColor;
    w->update();
}

void CNativeHandler::centralize(double r) {
    QWidget *desktop = qApp->desktop();
    if (w->parentWidget()) {
        desktop = w->parentWidget();
    }
    int dw = desktop->width();
    int dh = desktop->height();
    if (r > 0 && r <= 1) {
        w->resize(dw * r, dh * r);
    }
    w->move(desktop->x() + (dw - w->width()) / 2, desktop->y() + (dh - w->height()) / 2);
}

void CNativeHandler::maximize() {
    w->setWindowState(Qt::WindowMaximized);
}

void CNativeHandler::minimize() {
    w->setWindowState(Qt::WindowMinimized);
}

void CNativeHandler::normalize() {
    w->setWindowState(w->windowState() &
                      ~(Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen));
}

void CNativeHandler::fullScreen() {
    w->setWindowState(Qt::WindowFullScreen);
}

void CNativeHandler::showForward() {
}

void CNativeHandler::hideWindowFrame() {
    w->setWindowFlags(Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint |
                      Qt::WindowSystemMenuHint);
}

void CNativeHandler::updateResizable() {
}

void CNativeHandler::showEventEx(QShowEvent *event) {
    Q_UNUSED(event)
    if (w->x() < 0) {
        w->move(0, w->y());
    }
    if (w->y() < 0) {
        w->move(w->x(), 0);
    }
}

void CNativeHandler::paintEventEx(QPaintEvent *event) {
    QPainter painter(w);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setClipRegion(event->region());

    painter.setPen(Qt::NoPen);
    painter.setBrush(QBrush(m_borderColor));

    int b = w->layout() ? w->layout()->margin() : 0;
    painter.drawRect(0, 0, b, w->height());                      // Left
    painter.drawRect(w->width() - b, 0, b, w->height());         // Right
    painter.drawRect(b, 0, w->width() - 2 * b, b);               // Top
    painter.drawRect(b, w->height() - b, w->width() - 2 * b, b); // Bottom
}

void CNativeHandler::winIdChangeEventEx(QEvent *event) {
    Q_UNUSED(event)
}

void CNativeHandler::windowTitleChangeEventEx(QEvent *event) {
    Q_UNUSED(event)
}

void CNativeHandler::windowStateChangeEventEx(QWindowStateChangeEvent *event) {
    Q_UNUSED(event)
}

bool CNativeHandler::commonEventFilter(QEvent *event) {
    switch (event->type()) {
    case QEvent::Show:
        showEventEx(static_cast<QShowEvent *>(event));
        break;
    case QEvent::Paint:
        paintEventEx(static_cast<QPaintEvent *>(event));
        break;
    case QEvent::WinIdChange:
        winIdChangeEventEx(event);
        break;
    case QEvent::WindowTitleChange:
        windowTitleChangeEventEx(event);
        break;
    case QEvent::WindowStateChange:
        windowStateChangeEventEx(static_cast<QWindowStateChangeEvent *>(event));
        break;
    default:
        break;
    }
    return false;
}

bool CNativeHandler::nativeEventFilter(const QByteArray &eventType, void *message, long *result) {
    Q_UNUSED(eventType)
    Q_UNUSED(message)
    Q_UNUSED(result)
    return false;
}
